perm filename PAGE12.WEB[WEB,ALS] blob
sn#672763 filedate 1982-08-12 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 @* Reading the postamble.
C00013 ENDMK
C⊗;
@* Reading the postamble.
Now imagine that we are reading the \.{DVI} file and positioned just
four bytes after the |pst| command. That, in fact, is the situation,
when the following part of \.{DVItype} is called upon to read, translate,
and check the rest of the postamble.
@<Read, translate, and check the postamble@>=
begin print_ln('Postamble starts at byte ',pst_loc:0,'.');
@<Compute the conversion factor@>;
max_v←signed_quad; max_h←signed_quad; max_stack_depth←get_two_bytes;
print('maxv=',max_v:0,', maxh=',max_h:0,', maxstackdepth=',max_stack_depth:0);
m←get_two_bytes; print(', totalpages=',m:0);
if m=page_count then print_ln(' ')
else print_ln(' (should be',page_count:0,'!)');
@<Process the font definitions@>;
@<Make sure that the end of the file is well-formed@>;
end
@ We put the above module into a subprocedure to make a substantial
reduction in the size of the main procedure, which is otherwise marginally
too large for some compilers. We do this rather than making a barely
adequate fix because we want to gain the freedom to make minor changes to
the program in the future without having to worry about slight increases
in program size.
@<Declaration of subprocedure to read the |postamble|@>=
procedure read_postamble; {reads translates and checks the |postamble|}
var k: integer; {used as running variable in |for| statements}
begin
@<Read, translate, and check the postamble@>;
end;
@ The conversion factor |conv| is figured as follows: There are exactly
|n/d| \.{DVI} units per decimicron, and 254000 decimicrons per inch,
and |resolution| pixels per inch. Then we have to adjust this
by the stated amount of magnification.
@<Compute the conversion factor@>=
n←signed_quad; m←signed_quad;
if n≤0 then bad_dvi('numerator is ',n:0);
if m≤0 then bad_dvi('denominator is ',m:0);
print_ln('numerator/denominator=',n:0,'/',m:0);
conv←(n/254000.0)*(resolution/m);
n←signed_quad;
if new_mag>0 then n←new_mag
else if n≤0 then bad_dvi('magnification is ',n:0);
true_conv←conv; conv←true_conv*(n/1000.0);
print_ln('magnification=',n:0,'; ',conv:16:8,' pixels per DVI unit')
@ When we get to the present code, the phony `$-1$' font number has
just been read.
@<Make sure that the end of the file is well-formed@>=
q←signed_quad;
if q≠pst_loc then
print_ln('pst pointer in byte ',cur_loc-4:0,
@.pst pointer...should be...@>
' should be ',pst_loc:0,'!');
m←get_byte;
if m≠id_byte then print_ln('identification in byte ',cur_loc-1:0,
@.identification...should be...@>
' should be ',id_byte:0,'!');
k←cur_loc; m←223;
while (m=223)∧ not eof(dvi_file) do m←get_byte;
if not eof(dvi_file) then print_ln('signature in byte ',cur_loc-1:0,
@.signature...should be...@>
' should be 223!')
else if cur_loc<k+4 then
print_ln('not enough signature bytes at end of file (',
@.not enough signature bytes...@>
cur_loc-k:0,')');
@ The most complicated part of the postamble processing is the part
that we still have to tackle, namely the definitions of the fonts.
@<Process the font definitions@>=
font_num[nf]←signed_quad;
while font_num[nf]≠-1 do
begin if eof(dvi_file) then bad_dvi('endless font definitions');
if nf=max_fonts then abort('DVItype capacity exceeded (max fonts=',
@.DVItype capacity exceeded...@>
max_fonts:0,')!');
print('Font ',font_num[nf]:0,': ');
m←signed_quad; {the check sum}
q←signed_quad; {the scaled size}
d←signed_quad; {the design size}
@<Move font name into storage and into |cur_name|@>;
@<Load the font unless there are problems@>;
font_num[nf]←signed_quad;
end
@ We substitute question marks for non-ascii characters in the font name.
@<Move font name into storage and into |cur_name|@>=
p←get_byte; {length of the area/directory spec}
n←get_byte; {length of the font name proper}
if font_name[nf]+n+p>name_size then
abort('DVItype capacity exceeded (name size=',name_size:0,')!');
@.DVItype capacity exceeded...@>
if n+p=0 then bad_dvi('null font name');
font_name[nf+1]←font_name[nf]+n+p;
for k←font_name[nf] to font_name[nf+1]-1 do
begin r←get_byte;
if (r<" ")∨(r>"~") then names[k]←"?"@+else names[k]←r;
end;
incr(nf); print_font(nf-1); decr(nf);
@<Move font name into the |cur_name| string@>
@ If |p=0|, i.e., if no font directory has been specified, \.{DVItype}
is supposed to use the default font directory, which is a
system-dependent place where the standard fonts are kept.
The string variable |default_directory| contains the name of this area.
@↑system dependencies@>
@d default_directory_name=='<SYS.FONTS>' {change this to the correct name}
@d default_directory_name_length=11 {change this to the correct length}
@<Glob...@>=
@!default_directory:packed array[1..default_directory_name_length] of char;
@ @<Set init...@>=
default_directory←default_directory_name;
@ The string |cur_name| is supposed to be set to the external name of the
\.{TFM} file for the current font. This usually means that we need to
prepend the name of the default directory, and
to append the suffix `\.{.TFM}'. Furthermore, we change lower case letters
to upper case, since |cur_name| is a \PASCAL\ string.
@↑system dependencies@>
@<Move font name into the |cur_name| string@>=
for k←1 to name_length do cur_name[k]←' ';
if p=0 then
begin for k←1 to default_directory_name_length do
cur_name[k]←default_directory[k];
r←default_directory_name_length;
end
else r←0;
for k←font_name[nf] to font_name[nf+1]-1 do
begin incr(r);
if r+4>name_length then abort('Font name is too long!');
@.Font name is too long@>
if (names[k]≥"a")∧(names[k]≤"z") then
cur_name[r]←xchr[names[k]-@'40]
else cur_name[r]←xchr[names[k]];
end;
cur_name[r+1]←'.'; cur_name[r+2]←'T'; cur_name[r+3]←'F'; cur_name[r+4]←'M'
@ @<Load the font unless there are problems@>=
k←0;
while font_num[k]≠font_num[nf] do incr(k);
if k<nf then print_ln('---not loaded, this number already used!')
@.this number already used@>
else begin open_tfm_file;
if eof(tfm_file) then
print_ln('---not loaded, TFM file can''t be opened!')
@.TFM file can\'t be opened@>
else begin if (q≤0)∨(q≥@'1000000000) then
print_ln('---not loaded, bad scale (',q:0,')!')
@.bad scale@>
else if (d≤0)∨(d≥@'1000000000) then
print_ln('---not loaded, bad design size (',d:0,')!')
@.bad design size@>
else if in_TFM(q) then @<Finish loading the new font info@>;
end;
end
@ @<Finish loading...@>=
begin font_space[nf]←q div 6; {this is a 3-unit ``thin space''}
if (m≠0)∧(tfm_check_sum≠0)∧(m≠tfm_check_sum) then
begin print_ln('---loaded but beware: check sums do not agree!');
print_ln(' (',m:0,' vs. ',tfm_check_sum:0,')');
end
else print_ln('---loaded at size ',q:0,' DVI units');
d←trunc((100.0*conv*q)/(true_conv*d)+0.5);
if d≠100 then print_ln(' (this font is magnified ',d:0,'%)');
incr(nf); {now the new font is officially present}
end